package raft

import (
	"sync"
	"time"
)

func (rf *Raft) vote(term int, candidateId int, lastLogIndex int, lastLogTerm int) {
	defer rf.persist()
	count := 1
	cntMu := sync.Mutex{}
	for i, _ := range rf.peers {
		if i == candidateId {
			continue
		}
		args := RequestVoteArgs{
			Term:         term,
			CandidateId:  candidateId,
			LastLogIndex: lastLogIndex,
			LastLogTerm:  lastLogTerm,
		}
		go func(i int) {
			reply := RequestVoteReply{}
			ok := rf.peers[i].Call("Raft.RequestVote", &args, &reply)
			if ok {
				//If RPC request or response contains term T > currentTerm:
				//set currentTerm = T, convert to follower (§5.1)
				if reply.Term > term {
					rf.mu.Lock()
					rf.term = args.Term
					rf.votedFor = -1
					if rf.state != 0 {
						rf.changeState <- 0
					}
					rf.mu.Unlock()
				}
				if reply.VoteGranted {
					cntMu.Lock()
					count += 1
					cntMu.Unlock()
				}
			}
		}(i)
	}
	time.Sleep(time.Millisecond * 150)
	cntMu.Lock()
	if count*2 > len(rf.peers) {
		//初始化leader专有变量
		rf.mu.Lock()
		if rf.term == term {
			nextIdx, _ := rf.getLastLogIndexAndTerm()
			for i := 0; i < len(rf.peers); i++ {
				rf.nextIndex[i] = nextIdx + 1
				rf.matchIndex[i] = 0
			}
			rf.changeState <- 2
		}
		rf.mu.Unlock()
	}
	cntMu.Unlock()
}
